package com.goldplusgold.live.channel;

import com.example.videolib.BuildConfig;
import com.goldplusgold.live.protobuf.ChatProto;
import com.goldplusgold.network.lib.http.netty.ChannelBootstrapImpl;
import com.goldplusgold.network.lib.http.netty.ConnectionListener;

import java.util.concurrent.TimeUnit;

import io.netty.bootstrap.Bootstrap;
import io.netty.buffer.PooledByteBufAllocator;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.protobuf.ProtobufDecoder;
import io.netty.handler.codec.protobuf.ProtobufEncoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
import io.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
import io.netty.handler.timeout.IdleStateHandler;

/**
 * Created by Administrator on 2017/7/13.
 */
//TODO ip地址不要写死，在gradle中配置 by hur
public class LiveBootstrap extends ChannelBootstrapImpl {

    private String roomID;
    ResponseHandler.ReceiverMessageInterface receiverMessageInterface;
    ChannelFuture channelFuture;

    public LiveBootstrap(String roomID,ResponseHandler.ReceiverMessageInterface receiverMessageInterface){
        this.roomID = roomID;
        this.receiverMessageInterface = receiverMessageInterface;
    }
    @Override
    public void start() {
        try {
            channelFuture = init();
            channelFuture = channelFuture.sync();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void close() {
        if(channelFuture != null){
            channelFuture.channel().close();
        }
        if (bossGroup != null) {
            bossGroup.shutdownGracefully();
        }
    }

    @Override
    public void reset() {

    }

    @Override
    public ChannelFuture init() {
        if (bootstrap == null) {

            bossGroup = new NioEventLoopGroup();
            bootstrap = new Bootstrap();
            bootstrap.group(bossGroup)
                    .channel(NioSocketChannel.class)
                    .remoteAddress(BuildConfig.CHART_ROOT , BuildConfig.CHART_ROOT_PORT)
                    .option(ChannelOption.TCP_NODELAY, true)
                    .option(ChannelOption.SO_KEEPALIVE, true)
                    .option(ChannelOption.CONNECT_TIMEOUT_MILLIS, CONNECT_TIMEOUT_VALUE)
                    .option(ChannelOption.ALLOCATOR, new PooledByteBufAllocator(true))  //使用池化直接内存
                    .option(ChannelOption.RCVBUF_ALLOCATOR, new AdaptiveRecvByteBufAllocator())   //为接收的数据创建缓冲区,根据上一次大小自动调节
                    .handler(new ChannelInitializer<SocketChannel>() {
                        @Override
                        protected void initChannel(SocketChannel ch) throws Exception {
                            ch.pipeline()
                                    .addLast(new ProtobufVarint32FrameDecoder())
                                    .addLast(new ProtobufVarint32LengthFieldPrepender())
                                    .addLast(new ProtobufDecoder(ChatProto.ChatResponse.getDefaultInstance()))
                                    .addLast(new ProtobufEncoder())
                                    .addLast(new IdleStateHandler(0,2, 0, TimeUnit.MINUTES))
                                    .addLast(new LiveHeartbeatHandler())
                                    .addLast(new LiveInboundHandler(roomID))
                                    .addLast(new ResponseHandler(receiverMessageInterface));
                        }
                    });
        }
        return bootstrap.connect().addListener(new ConnectionListener<LiveBootstrap>(this));
    }
}
